package com.github.shiqiyue.myadmin.service.system.user;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.shiqiyue.myadmin.config.security.common.AuthorityCommon;
import com.github.shiqiyue.myadmin.entity.SessionUser;
import com.github.shiqiyue.myadmin.entity.system.*;
import com.github.shiqiyue.myadmin.mapper.system.UserMapper;
import com.github.shiqiyue.myadmin.service.system.button.ButtonService;
import com.github.shiqiyue.myadmin.service.system.commonlyauthority.CommonlyAuthorityService;
import com.github.shiqiyue.myadmin.service.system.menu.MenuService;
import com.github.shiqiyue.myadmin.service.system.role.RoleService;
import com.github.shiqiyue.myadmin.service.system.rolebutton.RoleButtonService;
import com.github.shiqiyue.myadmin.service.system.rolecommonlyauthority.RoleCommonlyAuthorityService;
import com.github.shiqiyue.myadmin.service.system.rolemenu.RoleMenuService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/***
 * 系统用户服务
 *
 * @author wwy
 *
 */
@Service("userService")
@Transactional(rollbackFor = RuntimeException.class)
public class UserService extends ServiceImpl<UserMapper, User> implements UserDetailsService {

    @Autowired
    private MenuService menuService;

    @Autowired
    private ButtonService buttonService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private RoleButtonService roleButtonService;

    @Autowired
    private CommonlyAuthorityService commonlyAuthorityService;

    @Autowired
    private RoleCommonlyAuthorityService roleCommonlyAuthorityService;


    /***
     * 通过name获得user
     *
     * @param name
     * @return
     * @throws Exception
     */
    public User getUserByName(String name) {
        User user = new User();
        user.setUsername(name);
        user.setDel(false);
        return baseMapper.selectOne(user);
    }

    /***
     * 更新最近登录信息
     *
     * @param userId
     * @param ip
     */
    public void updateLastLogin(String userId, String ip) {
        User user = new User();
        user.setLastLogin(new Date());
        user.setIp(ip);
        baseMapper.update(user, new EntityWrapper<User>().eq("id", userId));
    }


    public User selectByUsername(String username) {
        User user = new User();
        user.setUsername(username);
        return baseMapper.selectOne(user);
    }

    /***
     * 列出某角色下的所有用户
     * @param roleId
     * @return
     */
    public List<User> listByRoleId(String roleId) {
        return baseMapper.selectList(new EntityWrapper<User>().eq("roleId", roleId));

    }

    public Integer countByRoleId(String roleId) {
        return baseMapper.selectCount(new EntityWrapper<User>().eq("roleId", roleId));
    }


    /**
     * 列表
     *
     * @param page
     * @return
     * @throws Exception
     */
    public Page<User> list(Page<User> page, Map<String, Object> map) {
        page.setRecords(baseMapper.datalistPage(page, map));
        return page;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SessionUser sessionUser = new SessionUser();
        User user = selectByUsername(username);
        if (user != null) {
            Role role = roleService.selectById(user.getRoleId());
            user.setRole(role);
        }
        sessionUser.setUser(user);
        return sessionUser;
    }

    /***
     * 根据用户获取权限
     *
     * @param user
     * @return
     */
    public List<SimpleGrantedAuthority> getAuthoritiesByUser(User user) {
        List<SimpleGrantedAuthority> authorityList = new ArrayList<>(30);
        //增加角色信息
        authorityList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        if (user.getHasAllAuthority()) {
            // 超级管理员，获取全部权限
            return getAllGrantedAuthority(authorityList);
        }


        // 获取菜单权限

        List<RoleButton> roleButtonList = roleButtonService.selectMoreInfoByRoleId(user.getRoleId());
        List<RoleMenu> roleMenuList = roleMenuService.selectMoreInfoByRoleId(user.getRoleId());
        List<RoleCommonlyAuthority> roleCommonlyAuthorityList = roleCommonlyAuthorityService.selectMoreInfoByRoleId(user.getRoleId());
        for (RoleMenu roleMenu : roleMenuList) {
            // 链接如果为空，则跳过
            if (StringUtils.isBlank(roleMenu.getMenuUrl()) || roleMenu.getMenuUrl().trim().equals(Menu.EMPTY_URL)) {
                continue;
            }
            authorityList.add(new SimpleGrantedAuthority(roleMenu.getMenuUrl()));
        }
        for (RoleButton roleButton : roleButtonList) {
            if (StringUtils.isBlank(roleButton.getMenuUrl()) || StringUtils.isBlank(roleButton.getButtonAuthority())) {
                continue;
            }
            authorityList.add(new SimpleGrantedAuthority(
                    StringUtils.join(new String[]{roleButton.getMenuUrl(), roleButton.getButtonAuthority()},
                            AuthorityCommon.DELIMITER)));
        }
        for (RoleCommonlyAuthority roleCommonlyAuthority : roleCommonlyAuthorityList) {
            if (StringUtils.isBlank(roleCommonlyAuthority.getAuthorityName())) {
                continue;
            }
            authorityList.add(new SimpleGrantedAuthority(roleCommonlyAuthority.getAuthorityName()));
        }
        return authorityList;
    }

    /****
     * 获取全部权限
     *
     * @return
     */
    public List<SimpleGrantedAuthority> getAllGrantedAuthority(List<SimpleGrantedAuthority> authorityList) {
        List<Menu> menuList = menuService.selectList(new EntityWrapper<Menu>());
        List<Button> buttonList = buttonService.selectList(new EntityWrapper<Button>());
        List<CommonlyAuthority> commonlyAuthorityList = commonlyAuthorityService.selectList(new EntityWrapper<>());

        //增加角色信息
        authorityList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));

        for (Menu menu : menuList) {
            // 菜单权限,格式:菜单链接
            // 链接如果为空，则跳过
            if (StringUtils.isBlank(menu.getUrl()) || menu.getUrl().trim().equals(Menu.EMPTY_URL)) {
                continue;
            }
            authorityList.add(new SimpleGrantedAuthority(menu.getUrl()));
            for (Button button : buttonList) {
                // 按钮权限,格式:菜单链接:按钮权限名称
                authorityList.add(new SimpleGrantedAuthority(StringUtils
                        .join(new String[]{menu.getUrl(), button.getAuthorityName()}, AuthorityCommon.DELIMITER)));
            }
        }
        for (CommonlyAuthority commonlyAuthority : commonlyAuthorityList) {
            authorityList.add(new SimpleGrantedAuthority(commonlyAuthority.getAuthorityName()));
        }
        return authorityList;
    }

}
